#include "TextOutput.h"
#include "WindowHelper.h"
#include "SysMets.h"
#include "cstdio"
#include "windows.h"

USING_NS_LEARN;

int TextOutput::LearnEntry(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    Details::WindowHelper window(hInstance);
    window.RegisterWindowClass(WndProc);
    window.CreateWindowClass(TEXT("Learn"), nShowCmd, WS_OVERLAPPEDWINDOW | WS_VSCROLL);
    return window.EnterMainLoop();
}


LRESULT CALLBACK TextOutput::WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    PAINTSTRUCT ps;
    HDC hdc;
    static int cxChar, cyChar, cxCaps, cxClient, cyClient, ScrollPos;
    TEXTMETRIC tm;
    WCHAR szBuffer[10];

    switch (msg)
    {
    case WM_CREATE:
        hdc = GetDC(hWnd);
        GetTextMetrics(hdc, &tm);
        cxChar = tm.tmAveCharWidth;
        cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2;
        cyChar = tm.tmHeight + tm.tmExternalLeading;
        ReleaseDC(hWnd, hdc);

        SetScrollRange(hWnd, SB_VERT, 0, NUMLINES - 1, false);
        SetScrollPos(hWnd, SB_VERT, ScrollPos, true);

        return 0;
    case WM_SIZE:
        cxClient = LOWORD(lParam);
        cyClient = HIWORD(lParam);
        return 0; 
    case WM_VSCROLL:
        switch (LOWORD(wParam))
        {
        case SB_LINEDOWN:
            ++ScrollPos;
            break;
        case SB_LINEUP:
            --ScrollPos;
            break;
        case SB_PAGEDOWN:
            ScrollPos += cyClient / cyChar;
            break;
        case  SB_PAGEUP:
            ScrollPos -= cyClient / cyChar;
            break;
        case SB_THUMBPOSITION:
            ScrollPos = HIWORD(wParam);
        default:
            break;
        }

        ScrollPos = max(0, min(ScrollPos, NUMLINES - 1));
        if (ScrollPos != GetScrollPos(hWnd, SB_VERT))
        {
            SetScrollPos(hWnd, SB_VERT, ScrollPos, true);
            InvalidateRect(hWnd, nullptr, true);
        }
        return 0;
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        for (int i = 0; i < NUMLINES; ++i)
        {
            int y = cyChar * (i - ScrollPos);

            TextOut(hdc, 0, y, sysmetrics[i].szLabel, lstrlen(sysmetrics[i].szLabel));
            TextOut(hdc, 22 * cxCaps, y, sysmetrics[i].szDesc, lstrlen(sysmetrics[i].szDesc));
            SetTextAlign(hdc, TA_RIGHT | TA_TOP);
            TextOut(hdc, 22 * cxCaps + 40 * cxChar, y, szBuffer, 
                wsprintf(szBuffer, TEXT("%5d"), GetSystemMetrics(sysmetrics[i].iIndex)));
            SetTextAlign(hdc, TA_LEFT | TA_TOP);
        }
        EndPaint(hWnd, &ps);
        return 0;
    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;
    default:
        break;
    }
    return DefWindowProc(hWnd, msg, wParam, lParam);
}